package com.ctshk.app.iotc.controller;

import com.ctshk.common.annotations.OperationLogAnnotation;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.OperationLogModel;
import com.ctshk.common.enums.OperationLogType;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.web.support.BaseController;
import com.ctshk.rpc.iotc.dto.OperateBankPreferenceListDTO;
import com.ctshk.rpc.iotc.dto.OperateBankPreferenceQueryDTO;
import com.ctshk.rpc.iotc.req.*;
import com.ctshk.rpc.iotc.service.IOperateBankPreferenceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 银联优惠 前端控制器
 * </p>
 *
 * @author 谢诗宏
 * @since 2021-01-22
 */
@Api(value = "银联优惠-app", tags = "银联优惠-app")
@RestController
@RequestMapping("/operate/bank/preference-app")
public class OperateBankPreferenceController extends BaseController {

    @DubboReference
    private IOperateBankPreferenceService iOperateBankPreferenceService;

    @ApiOperation(value = "新增银联优惠-app", notes = "新增银联优惠-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.ADD, operTitle = "新增", operDesc = "新增银联优惠")
    @PostMapping("/add")
    public Result add(@RequestBody @Valid OperateBankPreferenceAddReq req) {
        return iOperateBankPreferenceService.add(req, getCurrentUser(getRequest()));
    }

    @ApiOperation(value = "编辑银联优惠-app", notes = "编辑银联优惠-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.UPDATE, operTitle = "编辑", operDesc = "编辑银联优惠")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid OperateBankPreferenceUpdateReq req) {
        return iOperateBankPreferenceService.update(req, getCurrentUser(getRequest()));
    }

    @ApiOperation(value = "修改银联优惠状态-app", notes = "修改银联优惠状态-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.UPDATE)
    @PostMapping("/updateStatus")
    public Result update(@RequestBody @Valid CodeStatusReq req) {
        return iOperateBankPreferenceService.updateStatus(req, getCurrentUser(getRequest()));
    }

    @ApiOperation(value = "提交审批-app", notes = "提交审批-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.UPDATE)
    @GetMapping("/approvalCode/{id}")
    public Result approvalCode(@PathVariable Long id) {
        return iOperateBankPreferenceService.approvalCode(id, getCurrentUser(getRequest()));
    }

    @ApiOperation(value = "查看银联优惠详情-app", notes = "查看银联优惠详情-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.QUERY)
    @PostMapping("/query")
    public Result<OperateBankPreferenceQueryDTO> query(@RequestBody @Valid OperateBankPreferenceQueryReq req) {
        return Result.success(iOperateBankPreferenceService.query(req));
    }

    @ApiOperation(value = "查询银联优惠列表-app", notes = "查询银联优惠列表-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.QUERY)
    @PostMapping("/list")
    public Result<PageResponse<OperateBankPreferenceListDTO>> list(@RequestBody OperateBankPreferenceListReq req) {
        return Result.success(iOperateBankPreferenceService.list(req, getCurrentUser(getRequest())));
    }

    @ApiOperation(value = "(提供内部接口)查询符合条件的银联优惠列表-app", notes = "查询银联优惠列表 TODO 要用的时候联系我这个好像有问题-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.QUERY)
    @PostMapping("/conformList")
    public Result<List<OperateBankPreferenceListDTO>> conformList(@RequestBody OperateBankConformReq req) {
        TokenUser currentUser = getCurrentUser(getRequest());
        req.setUserId(currentUser.getId());
        return Result.success(iOperateBankPreferenceService.conformList(req));
    }

    @ApiOperation(value = "(提供内部接口)扣减银联优惠剩余名额及剩余金额-app", notes = "扣减银联优惠剩余名额及剩余金额-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.UPDATE)
    @PostMapping("/deduct")
    public Result deduct(@RequestBody OperateBankDeductReq req) {
        return iOperateBankPreferenceService.deduct(req, getCurrentUser(getRequest()));
    }

    @ApiOperation(value = "(提供内部接口)查看并校验-app", notes = "查看并校验-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.QUERY)
    @PostMapping("/queryConform")
    public Result<OperateBankPreferenceQueryDTO> queryConform(@RequestBody @Valid OperateBankConformQueryReq req) {
        TokenUser currentUser = getCurrentUser(getRequest());
        req.setUserId(currentUser.getId());
        return iOperateBankPreferenceService.queryConform(req);
    }

    @ApiOperation(value = "(提供内部接口)退回银联优惠剩余名额及剩余金额-app", notes = "查看并校验-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.UPDATE)
    @PostMapping("/refundUpdate")
    public Result refundUpdate(@RequestBody @Valid OperateBankRefundReq req) {
        return iOperateBankPreferenceService.refundUpdate(req, getCurrentUser(getRequest()));
    }

    @ApiOperation(value = "导入银行卡号-app", notes = "导入银行卡号-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.QUERY)
    @PostMapping("/import")
    public Result<List<String>> importExcel(@RequestParam("file") MultipartFile file) throws Exception {
        // file为上传的后台接收到的前端文件，文件名称可访问，内容为字节数据需要转成POI专属的Workbook对象进行内容数据获取
        Assert.notNull(file, "上传文件不能为空");
        // 将输入的file文件转成POI的Excel文件对象Workbook
        String fileName = file.getOriginalFilename(); // 获取文件名
        Workbook workbook = null;
        if (StringUtils.endsWithIgnoreCase(fileName, "XLS")) {
            try {
                workbook = new HSSFWorkbook(file.getInputStream()); // XLS类型，2003Excel版本
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (StringUtils.endsWithIgnoreCase(fileName, "XLSX")) {
            try {
                workbook = new XSSFWorkbook(file.getInputStream()); // XLSX类型，2007Excel版本
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("文件类型不符,不是Excel文件 ");
        }
        // 解析Workbook对象，获取上传Excel内容（实际中，上传Excel文件需要按照指定规范编写上传）
        // 得到一个Sheet工作表
        Sheet sheet = workbook.getSheetAt(0);
        // 获得Sheet工作表的数据总行数（第0行开始）
        int totalRowNum = sheet.getLastRowNum();
        List<String> list = new ArrayList<>();
        for (int i = 1; i < totalRowNum; i++) {
            Cell cell = sheet.getRow(i).getCell(0);
            if (cell == null) {
                continue;
            }
            String cellValue = cell.getStringCellValue();
            list.add(cellValue);
        }
        return Result.success(list);

    }

    @ApiOperation(value = "查询符合业务类型对应的产品ID集合-app", notes = "查询符合业务类型对应的产品ID集合-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.QUERY)
    @GetMapping("/queryRelationIdList/{businessType}")
    public Result<List<Long>> queryRelationIdList(@PathVariable Integer businessType) {
        return Result.success(iOperateBankPreferenceService.queryRelationIdList(businessType));
    }

    @ApiOperation(value = "银联优惠审核-app", notes = "银联优惠审核-app")
    @OperationLogAnnotation(operModul = OperationLogModel.IOTC, operType = OperationLogType.UPDATE)
    @PostMapping("/approval")
    public Result approval(@RequestBody @Valid OperateBankApprovalReq req) {
        req.setUserId(getCurrentUser(getRequest()).getId());
        return iOperateBankPreferenceService.approval(req);
    }
}